package com.hengpeng.itfin.service.investinfo.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hengpeng.common.exception.ServiceResult;
import com.hengpeng.common.persist.query.DynamicQuery;
import com.hengpeng.common.util.DateTimeUtil;
import com.hengpeng.itfin.common.SystemConfigUtil;
import com.hengpeng.itfin.constants.SystemConfigConstants;
import com.hengpeng.itfin.service.impl.BaseServiceImpl;
import com.hengpeng.itfin.service.investinfo.InvestInfoService;
import com.hengpeng.itfinbase.constants.RespCodeConstants;
import com.hengpeng.itfinbase.idAssign.ID;
import com.hengpeng.itfinbase.message.ResponseMessage;
import com.hengpeng.itfinbase.message.partner.InvestInfoRequestMsg;
import com.hengpeng.itfinbase.message.partner.InvestInfoResponseMsg;
import com.hengpeng.itfinbase.message.partner.PartnerTransType;
import com.hengpeng.itfinbase.message.partner.QueryTransStatRequest;
import com.hengpeng.itfinbase.message.partner.QueryTransStatResponse;
import com.hengpeng.itfinbase.persist.AccountLog;
import com.hengpeng.itfinbase.persist.BorrowInfo;
import com.hengpeng.itfinbase.persist.BorrowInfo.BorrowStatus;
import com.hengpeng.itfinbase.persist.InvestInfo;
import com.hengpeng.itfinbase.persist.InvestInfo.InvestStatus;
import com.hengpeng.itfinbase.persist.UserInfo;

@Service
@Lazy
@Transactional
public class InvestInfoServiceImpl extends BaseServiceImpl implements InvestInfoService
{
	@Override
	public InvestInfo getInvestByUnFreeOrderId(String unFreeOrderId, boolean isLock)
	{
		DynamicQuery query = new DynamicQuery(InvestInfo.class);
		query.eq("unFreeOderId", unFreeOrderId);
		InvestInfo investInfo = serviceFactory.getPersistService().getByDynamicQuery(InvestInfo.class, query);
		if (isLock && investInfo != null)
		{
			investInfo = serviceFactory.getPersistService().lockObject(InvestInfo.class, investInfo.getId());
		}
		return investInfo;
	}

	/**
	 * <pre>
	 *  投资接口调用成功后操作：
	 *                        1,更新投资信息状态 
	 *                        2,冻结投资人资金信息表中相关资金。 
	 *                        3,添加资金流水表相关资金冻结流水。
	 *                        4,判断投标总金额是否已经达到募集金额，如果达到募集金额则设置标的状态为：募集结束
	 *  投资接口调用失败后操作：
	 *                        1,释放投资额度,更新标的信息表中的已募集金额,已募集人数。 
	 *                        2,更新投标信息状态为：失败
	 * </pre>
	 */
	@Override
	public ServiceResult<String> dealInvestResult(InvestInfoResponseMsg response) {
		ServiceResult<String> result = new ServiceResult<String>();
		if (response == null || !RespCodeConstants.CommonCode.TRANS_SUC.equals(response.getRespCode())) {
			result.setIsSuccess(false);
			// 失败
			InvestInfo investInfo = serviceFactory.getDaoFactory().getInvestInfoDao().get(Long.parseLong(response.getOrdId()));
			if (investInfo != null && investInfo.getStatus().equals(InvestStatus.INVESTING)) {
				int i = serviceFactory.getDaoFactory().getInvestInfoDao().updateStatus(investInfo.getId(), InvestStatus.INVESTING, InvestStatus.FAILURE);
				if (i > 0) {
					BorrowInfo borrowInfo = serviceFactory.getDaoFactory().getBorrowInfoDao().get(investInfo.getBorrowInfoId());
					if (borrowInfo != null && borrowInfo.getStatus().equals(BorrowStatus.RAISE)) {
						// 释放额度
						borrowInfo.setRaiseMoney(borrowInfo.getRaiseMoney() - investInfo.getInvestMoney());
						borrowInfo.setRaiseNum(borrowInfo.getRaiseNum() - 1);
						serviceFactory.getDaoFactory().getBorrowInfoDao().update(borrowInfo);
					} else {
						result.setMessage(RespCodeConstants.BorrowInfoCode.BORROWINFO_UNKONW_MSG);
						result.setCode(RespCodeConstants.BorrowInfoCode.BORROWINFO_UNKONW);
					}
				}
			} else {
				result.setMessage(RespCodeConstants.CommonCode.TRANS_FAIL);
				result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL_MSG);
			}
			return result;
		} else if (RespCodeConstants.CommonCode.TRANS_SUC.equals(response.getRespCode())) {
			// 成功
			InvestInfo investInfo = serviceFactory.getDaoFactory().getInvestInfoDao().get(Long.parseLong(response.getOrdId()));
			if (investInfo != null && investInfo.getStatus().equals(InvestStatus.INVESTING)) {
				int i = serviceFactory.getDaoFactory().getInvestInfoDao().updateStatusAndFreeId(investInfo.getId(),
						response.getFreezeTrxId(), InvestStatus.INVESTING, InvestStatus.SUCESS);
				if (i > 0) {
					investInfo.setFreezeTrxId(response.getFreezeTrxId());// 设置冻结标识
					investInfo.setStatus(InvestStatus.SUCESS);
					BorrowInfo borrowInfo = serviceFactory.getDaoFactory().getBorrowInfoDao().get(investInfo.getBorrowInfoId());
					if (borrowInfo != null) {
						/**
						 * 满标设置筹款结束
						 */
						if (borrowInfo.getRaiseMoney().longValue() == borrowInfo.getBorrowMoney().longValue()) {
							borrowInfo.setStatus(BorrowStatus.END);
							serviceFactory.getDaoFactory().getBorrowInfoDao().update(borrowInfo);
						}
					} else {
						result.setIsSuccess(false);
						result.setMessage(RespCodeConstants.BorrowInfoCode.BORROWINFO_UNKONW_MSG);
						result.setCode(RespCodeConstants.BorrowInfoCode.BORROWINFO_UNKONW);
						return result;
					}
					/**
					 * 更新投资人资金信息,添加资金流水
					 */
					serviceFactory.getAccountService().changeAccountMoney(investInfo.getInvestUserId(),
							investInfo.getInvestMoney(), AccountLog.TransType.INVEST, AccountLog.TradeMode.FREEZE,
							investInfo.getId().toString(), "投标成功");
				}
				result.setCode(RespCodeConstants.CommonCode.TRANS_SUC);
				result.setMessage(RespCodeConstants.CommonCode.TRANS_SUC_MSG);
				result.setIsSuccess(true);
			} else {
				result.setIsSuccess(true);
				result.setMessage(RespCodeConstants.CommonCode.TRANS_SUC_MSG);
				result.setCode(RespCodeConstants.CommonCode.TRANS_SUC);
			}
		}
		return result;
	}

	@Override
	public void investQuery()
	{
		try
		{
			List<InvestInfo> list = serviceFactory.getDaoFactory().getInvestInfoDao()
					.queryList(null, new InvestStatus[] { InvestStatus.INVESTING });
			if (list != null && list.size() > 0)
			{
				List<Future<Long>> rtList = new ArrayList<Future<Long>>();
				ExecutorService execute = Executors.newFixedThreadPool(list.size());
				for (final InvestInfo iv : list)
				{
					Future<Long> submit = execute.submit(new Callable<Long>()
					{
						public Long call()
						{
							try
							{
								serviceFactory.getInvestInfoService().doInvestQuery(iv);
							}
							catch (Throwable e)
							{
								logger.error("投标状态查询线程异常", e);
							}
							return 0L;
						}
					});
					rtList.add(submit);
				}
				execute.shutdown();
				for (Future<Long> future : rtList)
				{
					future.get();
				}
			}
		}
		catch (Throwable e)
		{
			logger.error("投标状态查询线程异常", e);
		}
	}

	@Override
	public void doInvestQuery(InvestInfo investInfo)
	{
		Date time = DateTimeUtil.addSecond(investInfo.getCreateTime(),
				Long.parseLong(SystemConfigUtil.getConfigValue(SystemConfigConstants.INVEST_LIMIT_TIME)));
		if (time.getTime() < System.currentTimeMillis())
		{
			/**
			 * <pre>
			 * 当投资人投标时,超过指定时间还未完成支付,则系统进行交易状态查询,
			 * 查询结果若为交易失败,则进行释放融资额度操作
			 * 查询结果若为交易成功,则进行交易信息的补充成功操作.
			 * </pre>
			 */
			QueryTransStatRequest request = new QueryTransStatRequest();
			request.setOrdId(investInfo.getFreeOderId());
			request.setOrdDate(DateTimeUtil.formatToStr(investInfo.getCreateTime(), DateTimeUtil.DATE_FORMAT_YYYYMMDD));
			request.setPartnerTransType(PartnerTransType.QueryTransStat);
			request.setQueryTransType("FREEZE");
			QueryTransStatResponse response = (QueryTransStatResponse) serviceFactory.getPartnerService().request(
					request);
			if ("F".equals(response.getTransStat()) || "U".equals(response.getTransStat()))
			{
				final InvestInfoResponseMsg investResponse = new InvestInfoResponseMsg();
				investResponse.setOrdId(investInfo.getId().toString());
				if ("F".equals(response.getTransStat()))
				{// 成功冻结
					investResponse.setRespCode(RespCodeConstants.CommonCode.TRANS_SUC);
					investResponse.setRespDesc(RespCodeConstants.CommonCode.TRANS_SUC_MSG);
					investResponse.setFreezeTrxId(response.getTrxId());
				}
				else if ("U".equals(response.getTransStat()))
				{// 未冻结
					investResponse.setRespCode(RespCodeConstants.CommonCode.TRANS_FAIL);
					investResponse.setRespDesc(RespCodeConstants.CommonCode.TRANS_FAIL_MSG);
				}
				ServiceResult<String> resulst = serviceFactory.getInvestInfoService().dealInvestResult(
						investResponse);
				logger.info("投标状态查询定时作业：投标id:" + investResponse.getOrdId() + ",响应消息:" + resulst.getMessage()
						+ ",响应码:" + resulst.getCode() + "");
					
			}
		}
	}

	@Override
	public ResponseMessage packInvestRequest(InvestInfoRequestMsg reqMsg)
	{
		ResponseMessage response = new ResponseMessage();
		/**
		 * 借款前先占据借款额度
		 */
		BorrowInfo borrowInfo = serviceFactory.getDaoFactory().getBorrowInfoDao()
				.getBorrowInfo(Long.parseLong(reqMsg.getBorrowInfoId()), BorrowInfo.BorrowStatus.RAISE);
		int i = serviceFactory.getDaoFactory().getBorrowInfoDao().updateRaiseMoney(borrowInfo.getId(), Long.parseLong(reqMsg.getTransAmt()));
		if (i > 0) {
			UserInfo investUserInfo = serviceFactory.getPersistService().get(UserInfo.class,Long.parseLong(reqMsg.getInvestUserId()));
			/**
			 * 生成并保存投资信息
			 */
			InvestInfo investInfo = new InvestInfo();
			investInfo.setUserLevel(investUserInfo.getUserLevel());
			investInfo.setInvestUserName(reqMsg.getInvestUserName());
			investInfo.setInvestUserId(Long.parseLong(reqMsg.getInvestUserId()));
			investInfo.setInvestUserTrustAccountId(reqMsg.getUsrCustId());
			investInfo.setNowOwnUserId(Long.parseLong(reqMsg.getInvestUserId()));
			investInfo.setNowOwnUserTrustAccountId(reqMsg.getUsrCustId());
			investInfo.setNowOwnUserName(reqMsg.getInvestUserName());
			investInfo.setBorrowInfoId(Long.parseLong(reqMsg.getBorrowInfoId()));
			investInfo.setBorrowName(reqMsg.getBorrowName());
			investInfo.setInvestMoney(Long.parseLong(reqMsg.getTransAmt()));
			investInfo.setInvestTime(new Date());
			investInfo.setStatus(InvestInfo.InvestStatus.INVESTING);
			investInfo.setCreateTime(new Date());
			investInfo.setUpdateTime(new Date());
			String freeOderId = ID.getInstanse().getID(18).toString();
			investInfo.setFreeOderId(freeOderId);
			investInfo = serviceFactory.getPersistService().save(investInfo);
			reqMsg.setInvestInfoId(investInfo.getId());
			reqMsg.setOrdDate(DateTimeUtil.formatToStr(new Date(), DateTimeUtil.DATE_FORMAT_YYYYMMDD));
			reqMsg.setFreezeOrdId(freeOderId);
		} else {
			response.setRespCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			response.setRespDesc("借款额度已满");
		}
		return response;
	}
}
